package com.gonsin.ta.logic.node;

import com.gonsin.ta.logic.TA;
import com.gonsin.ta.logic.exceptions.TaException;
import com.gonsin.ta.logic.parse.condition.context.ChainContextImpl;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 节点执行器 - 自定的执行策略需要实现该类
 *
 * @author sikadai
 * @since 2.6.9
 */
@Slf4j
public abstract class NodeExecutor {

    //执行器执行入口-若需要更大维度的执行方式可以重写该方法
    public void execute(NodeComponentProxy instance, ChainContextImpl context) throws Exception {
//        if(TA.LOG){
//            TA.log().info("TA - 准备执行chainId = 【{}】中的节点【{}】", context.getChainId(), instance.getNodeId());
//        }
//        int retryCount = instance.getRetryCount();
//        List<Class<? extends Exception>> forExceptions = instance.getRetryForExceptions();
//        for (int i = 0; i <= retryCount; i++) {
//            try {
//                // 先执行一次
//                if (i == 0) {
                    instance.execute(context);
//                } else {
//                    // 进入重试逻辑
//                    retry(instance, i, context);
//                }
//                break;
//            } catch (TaException e) {
//                //如果是ChainEndException，则无需重试
//                throw e;
//            } catch (Exception e) {
//                //判断抛出的异常是不是指定异常的子类
//                boolean flag = forExceptions.stream().anyMatch(clazz -> clazz.isAssignableFrom(e.getClass()));
//                //两种情况不重试，1)抛出异常不在指定异常范围内 2)已经重试次数大于等于配置次数
//                if (!flag || i >= retryCount) {
//                    throw e;
//                }
//            }
//        }
    }

    //执行重试逻辑 - 子类通过实现该方法进行重试逻辑的控制
    protected void retry(NodeComponentProxy instance, int currentRetryCount, ChainContextImpl context) throws Exception {
        if(TA.LOG){
            TA.log().info("TA - 第{}次重试【{}】", currentRetryCount + 1, instance.getNodeId());
        }
        //执行业务逻辑的主要入口
        instance.execute(context);
    }
}
